/**
 * Copyright (C) 2008+ Saifeng Zeng
 *		 2008+ Spark Zheng
 *
 * test/test_bit.c
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "global.h"
#include "bit.h"

int main(int argc, char *argv[])
{
	if (argc < 2) {
		fprintf(stderr, "Usage: test_bit "
			"[a(atomic)|b(bit_operations)]\n");
		return -1;
	}
	
if (strchr(argv[1], 'a') != NULL) {
	dlib_atomic_t t_a;
	dlib_atomic_init(&t_a, 10);

	fprintf(stdout, "BIT: test_bit begin atomic operations test...\n");
	
	fprintf(stdout, "   dlib_atomic_inc(%ld):", dlib_atomic_get(&t_a));
	dlib_atomic_inc(&t_a);
	fprintf(stdout, " %ld .\n", dlib_atomic_get(&t_a));
	
	fprintf(stdout, "   dlib_atomic_dec(%ld):", dlib_atomic_get(&t_a));
	dlib_atomic_dec(&t_a);
	fprintf(stdout, " %ld .\n", dlib_atomic_get(&t_a));
	
	long t_b = 5;
	fprintf(stdout, "   dlib_atomic_add(%ld, %ld):", dlib_atomic_get(&t_a), t_b);
	dlib_atomic_add(&t_a, t_b);
	fprintf(stdout, " %ld .\n", dlib_atomic_get(&t_a));
	
	fprintf(stdout, "   dlib_atomic_sub(%ld, %ld):", dlib_atomic_get(&t_a), t_b);
	dlib_atomic_sub(&t_a, t_b);
	fprintf(stdout, " %ld .\n", dlib_atomic_get(&t_a));
	
	fprintf(stdout, "   dlib_atomic_xadd(%ld, %ld):", dlib_atomic_get(&t_a), t_b);
	t_b = dlib_atomic_xadd(&t_a, t_b);
	fprintf(stdout, "t_a is %ld, t_b is %ld .\n", dlib_atomic_get(&t_a), t_b);
	
	fprintf(stdout, "   dlib_atomic_xsub(%ld, %ld):", dlib_atomic_get(&t_a), t_b);
	t_b = dlib_atomic_xsub(&t_a, t_b);
	fprintf(stdout, "t_a is %ld, t_b is %ld .\n", dlib_atomic_get(&t_a), t_b);
	
	fprintf(stdout, "   dlib_atomic_xchg(%ld, %ld):", dlib_atomic_get(&t_a), t_b);
	t_b = dlib_atomic_xchg(&t_a, t_b);
	fprintf(stdout, "t_a is %ld, t_b is %ld .\n", dlib_atomic_get(&t_a), t_b);
	
	dlib_atomic_set(&t_a, 5);
	t_b = 10;
	long t_c = 5;
	fprintf(stdout, "   dlib_atomic_cas(%ld, %ld, %ld):", dlib_atomic_get(&t_a), t_b, t_c);
	t_c = dlib_atomic_cas(&t_a, t_b, t_c);
	fprintf(stdout, "t_a is %ld, t_b is %ld, t_c is %ld .\n", dlib_atomic_get(&t_a), t_b, t_c);
	fprintf(stdout, "   dlib_atomic_cas(%ld, %ld, %ld):", dlib_atomic_get(&t_a), t_b, t_c);
	t_c = dlib_atomic_cas(&t_a, t_b, t_c);
	fprintf(stdout, "t_a is %ld, t_b is %ld, t_c is %ld .\n", dlib_atomic_get(&t_a), t_b, t_c);
	
	dlib_atomic_set(&t_a, 0x3C3C);
	long t_mask = 0xC3C3;
	fprintf(stdout, "   dlib_atomic_xand(0x%lX, 0x%lX):", dlib_atomic_get(&t_a), t_mask);
	t_b = dlib_atomic_xand(&t_a, t_mask);
	fprintf(stdout, "t_a is 0x%lX, return t_b is 0x%lX .\n", dlib_atomic_get(&t_a), t_b);
	
	dlib_atomic_set(&t_a, 0x3C3C);
	t_mask = 0xC3C3;
	fprintf(stdout, "   dlib_atomic_xoor(0x%lX, 0x%lX):", dlib_atomic_get(&t_a), t_mask);
	t_b = dlib_atomic_xoor(&t_a, t_mask);
	fprintf(stdout, "t_a is 0x%lX, return t_b is 0x%lX .\n", dlib_atomic_get(&t_a), t_b);
	
	fprintf(stdout, "BIT: test_bit atomic operations successfully end.\n");
}
	
	
if (strchr(argv[1], 'b') != NULL) {
	uint32_t u_32 = 0x3C3CA5A5;
	
	uint64_t u_64 = 0x3C3C3C3CA5A5A5A5LLU;

	int n_32 = 8;
	int m_32 = 4;
	int n_64 = 48;
	int m_64 = 24;
	
	int64_t ret = 0;

	fprintf(stdout, "------------------------------------------\n");
	fprintf(stdout, "BIT: test_bit begin bit operations test...\n");
	
	fprintf(stdout, "   DLIB_TEST_BIT(0x%X, %d):", u_32, 7);
	ret = DLIB_TEST_BIT(u_32, 7);
	fprintf(stdout, "%lld \n", ret);
	fprintf(stdout, "   DLIB_SET_BIT(0x%X, %d):", u_32, 7);
	DLIB_SET_BIT(u_32, 7);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_CLEAR_BIT(0x%X, %d):", u_32, 7);
	DLIB_CLEAR_BIT(u_32, 7);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_REVERSE_BIT(0x%X, %d):", u_32, 7);
	DLIB_REVERSE_BIT(u_32, 7);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_TEST_BIT64(0x%llX, %d):", u_64, 47);
	ret = DLIB_TEST_BIT64(u_64, 47);
	fprintf(stdout, "%lld \n", ret);
	fprintf(stdout, "   DLIB_SET_BIT64(0x%llX, %d):", u_64, 47);
	DLIB_SET_BIT64(u_64, 47);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_CLEAR_BIT64(0x%llX, %d):", u_64, 47);
	DLIB_CLEAR_BIT64(u_64, 47);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_REVERSE_BIT64(0x%llX, %d):", u_64, 47);
	DLIB_REVERSE_BIT64(u_64, 47);
	fprintf(stdout, "0x%llX \n", u_64);
	
	fprintf(stdout, "   DLIB_SET_END_ZERO(0x%X, %d):", u_32, n_32);
	DLIB_SET_END_ZERO(u_32, n_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SET_END_ONE(0x%X, %d):", u_32, n_32);
	DLIB_SET_END_ONE(u_32, n_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SET_END_REVERSE(0x%X, %d):", u_32, n_32);
	DLIB_SET_END_REVERSE(u_32, n_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_SET_END_ZERO64(0x%llX, %d):", u_64, n_64);
	DLIB_SET_END_ZERO64(u_64, n_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SET_END_ONE64(0x%llX, %d):", u_64, n_64);
	DLIB_SET_END_ONE64(u_64, n_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SET_END_REVERSE64(0x%llX, %d):", u_64, n_64);
	DLIB_SET_END_REVERSE64(u_64, n_64);
	fprintf(stdout, "0x%llX \n", u_64);
	
	fprintf(stdout, "   DLIB_SET_SEGMENT_ZERO(0x%X, %d, %d):", u_32, n_32, m_32);
	DLIB_SET_SEGMENT_ZERO(u_32, n_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SET_SEGMENT_ONE(0x%X, %d, %d):", u_32, n_32, m_32);
	DLIB_SET_SEGMENT_ONE(u_32, n_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SET_SEGMENT_REVERSE(0x%X, %d, %d):", u_32, n_32, m_32);
	DLIB_SET_SEGMENT_REVERSE(u_32, n_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_SET_SEGMENT_ZERO64(0x%llX, %d, %d):", u_64, n_64, m_64);
	DLIB_SET_SEGMENT_ZERO64(u_64, n_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SET_SEGMENT_ONE64(0x%llX, %d, %d):", u_64, n_64, m_64);
	DLIB_SET_SEGMENT_ONE64(u_64, n_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SET_SEGMENT_REVERSE64(0x%llX, %d, %d):", u_64, n_64, m_64);
	DLIB_SET_SEGMENT_REVERSE64(u_64, n_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	
	
	fprintf(stdout, "   DLIB_SHR_WITH_ZERO(0x%X, %d):", u_32, m_32);
	DLIB_SHR_WITH_ZERO(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SHL_WITH_ZERO(0x%X, %d):", u_32, m_32);
	DLIB_SHL_WITH_ZERO(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SHR_WITH_ONE(0x%X, %d):", u_32, m_32);
	DLIB_SHR_WITH_ONE(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SHL_WITH_ONE(0x%X, %d):", u_32, m_32);
	DLIB_SHL_WITH_ONE(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_SHR_WITH_ZERO64(0x%llX, %d):", u_64, m_64);
	DLIB_SHR_WITH_ZERO64(u_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SHL_WITH_ZERO64(0x%llX, %d):", u_64, m_64);
	DLIB_SHL_WITH_ZERO64(u_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SHR_WITH_ONE64(0x%llX, %d):", u_64, m_64);
	DLIB_SHR_WITH_ONE64(u_64, m_64);
	fprintf(stdout, "0x%llX \n", u_64);
	fprintf(stdout, "   DLIB_SHL_WITH_ONE64(0x%llX, %d):", u_64, m_64);
	DLIB_SHL_WITH_ONE64(u_32, m_32);
	fprintf(stdout, "0x%llX \n", u_64);
	
	fprintf(stdout, "   DLIB_SHR(0x%X, %d):", u_32, m_32);
	DLIB_SHR(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SHL(0x%X, %d):", u_32, m_32);
	DLIB_SHL(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SAR(0x%X, %d):", u_32, m_32);
	DLIB_SAR(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_ROR(0x%X, %d):", u_32, m_32);
	DLIB_ROR(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_ROL(0x%X, %d):", u_32, m_32);
	DLIB_ROL(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);
	fprintf(stdout, "   DLIB_SAL(0x%X, %d):", u_32, m_32);
	DLIB_SAL(u_32, m_32);
	fprintf(stdout, "0x%X \n", u_32);

	fprintf(stdout, "   DLIB_GET_RIGHT(0x%X, %d):", u_32, n_32);
	DLIB_GET_RIGHT(u_32, n_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_GET_RIGHT64(0x%llX, %d):", u_64, n_64);
	DLIB_GET_RIGHT64(u_64, n_64);
	fprintf(stdout, "0x%llX \n", u_64);
	
	
	fprintf(stdout, "   DLIB_SET_RIGHT_ZEROS(0x%X):", u_32);
	DLIB_SET_RIGHT_ZEROS(u_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_SET_RIGHT_ZEROS64(0x%llX):", u_64);
	DLIB_SET_RIGHT_ZEROS64(u_64);
	fprintf(stdout, "0x%llX \n", u_64);
	
	fprintf(stdout, "   DLIB_CLEAR_RIGHT_ONES(0x%X):", u_32);
	DLIB_CLEAR_RIGHT_ONES(u_32);
	fprintf(stdout, "0x%X \n", u_32);
	
	fprintf(stdout, "   DLIB_CLEAR_RIGHT_ONES64(0x%llX):", u_64);
	DLIB_CLEAR_RIGHT_ONES64(u_64);
	fprintf(stdout, "0x%llX \n", u_64);
	
	
	u_32 = 0x3C3CA5A5;
	uint32_t r = 0;
	fprintf(stdout, "   DLIB_COUNT_ONES(0x%X, %d):", u_32, r);
	DLIB_COUNT_ONES(u_32, r);
	fprintf(stdout, "%d \n", r);
	
	fprintf(stdout, "   DLIB_INVERTED_SEQUENCE(0x%X, %d):", u_32, r);
	DLIB_INVERTED_SEQUENCE(u_32, r);
	fprintf(stdout, "0x%X \n", r);
	
	u_64 = 0x3C3C3C3CA5A5A5A5LLU;
	uint64_t r_64 = 0;
	fprintf(stdout, "   DLIB_COUNT_ONES64(0x%llX, %lld):", u_64, r_64);
	DLIB_COUNT_ONES64(u_64, r_64);
	fprintf(stdout, "%lld \n", r_64);
	
	fprintf(stdout, "   DLIB_INVERTED_SEQUENCE64(0x%llX, %lld):", u_64, r_64);
	DLIB_INVERTED_SEQUENCE64(u_64, r_64);
	fprintf(stdout, "0x%llX \n", r_64);
	
	fprintf(stdout, "BIT: test_bit bit operations successfully end.\n");
	fprintf(stdout, "----------------------------------------------\n");
}

	return 0;
}
